#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include "config.h"
#include "highscore_io.h"
#include "rockdodger_globals.h"

// High score table
struct highscore high[] = {
  {1300, "Pad", 2, 0},
  {1250, "Pad", 2, 0},
  {650, "Pad", 1, 0},
  {500, "Pad", 1, 0},
  {300, "Pad", 1, 0},
  {250, "Pad", 1, 0},
  {200, "Pad", 1, 0},
  {150, "Pad", 1, 0}
};

const unsigned int MAXIMUM_HIGH_SCORE_ENTRIES =
  sizeof(high) / sizeof(struct highscore);
long score = 0;

static const char *HIGHSCORE_HEADER_FORMAT = "rockdodger highscore %x\n";
static const int HIGHSCORE_VERSION = 2;

FILE *hs_fopen(const char *mode) {
  mode_t mask;
  char s[1024];
  FILE *f = NULL;

  s[sizeof(s) - 1] = '\0';
  snprintf(s, sizeof(s) - 1, "%s/rockdodger.scores", GAMESDIR);
  mask = umask(0111);
  if((f = fopen(s, mode)) == NULL) {
    umask(0117);
    snprintf(s, sizeof(s) - 1, "%s/.rockdodger_high", getenv("HOME"));
    if((f = fopen(s, mode)) == NULL) {
      fprintf(stderr, "Could not open highscore file '%s', mode '%s'!\n", s,
	      mode);
    }
  }
  umask(mask);
  return f;
}

void read_high_score_table() {
  FILE *f;
  int i, giveup = 0;
  if((f = hs_fopen("r")) != NULL) {
    // If the file exists, read from it
    if(fscanf(f, HIGHSCORE_HEADER_FORMAT, &i) == 1) {
      if(i == HIGHSCORE_VERSION) {
	for(i = 0; i < MAXIMUM_HIGH_SCORE_ENTRIES && !giveup; ++i) {
	  char s[1024];
	  long int highscore;

	  if(high[i].allocated) {
	    free(high[i].name);
	    high[i].allocated = 0;
	  }

	  switch (fscanf(f, "%ld%1023[ ]%1023[^\n]", &highscore, s, s)) {
	  case 3:
	    high[i].name = strdup(s);
	    high[i].score = highscore;
	    high[i].allocated = 1;
	    break;
	  case 2:
	  case 1:
	    high[i].name = "";
	    high[i].score = highscore;
	    high[i].allocated = 0;
	    break;
	  default:
	    giveup = 1;
	    break;
	  }
	}
      }
    }
    fclose(f);
  }
}

void write_high_score_table() {
  FILE *f;
  int i;
  if((f = hs_fopen("w")) != NULL) {
    // If the file exists, write to it
    fprintf(f, HIGHSCORE_HEADER_FORMAT, HIGHSCORE_VERSION);
    for(i = 0; i < MAXIMUM_HIGH_SCORE_ENTRIES; ++i) {
      fprintf(f, "%ld %s\n", high[i].score, high[i].name);
    }
    fclose(f);
  }
}


void inc_score(int x, int y, long dscore) {
  score += dscore;
}

long clear_score(void) {
  long old = score;
  score = 0.0;
  return old;
}
